﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////
#include "StructureInstancePresetParameterUtils.h"
#include "GbmpBuiltInCategoryUniIdentitiesNew.h"
#include "GbmpBuiltInParameterDefinitionsNew.h"
#include "GcmpBuiltInParameterDefinitions.h"
#include "IDocument.h"
#include "IElement.h"
#include "IElementBasicInformation.h"
#include "IParameter.h"
#include "IParameterDefinitionLibrary.h"
#include "IPresetParameterManager.h"
#include "StructureFamilyUtils.h"

#include "EnableCompileWarning_The_LAST_IncludeInCpp.h"
using namespace gcmp;

#define DOC_PARAMETER_ID(DOCUMENT, BUILTIN_PARAM_NAME) \
    IParameterDefinitionLibrary::Get(DOCUMENT)->GetParameterDefinitionIdByUid(PARAMETER_UID(BUILTIN_PARAM_NAME))

bool StructureInstancePresetParameterUtils::GetPresetFamilyNameAndInstanceType(const IDocument* pDoc, const UniIdentity& categoryUid, Int32 categorySecondKey, std::wstring& familyName, std::wstring& instanceType)
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");

    IPresetParameterManager* pPresetMgr = IPresetParameterManager::Get(pDoc);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pPresetMgr, L"pPresetMgr为空",L"GDMPLab",L"2024-03-30");

    ElementId preSetTypeId;
    if(!pPresetMgr->GetPresetType(categoryUid, categorySecondKey, preSetTypeId))
    {
        return false;
    }

    std::wstring tmpFamilyName;
    std::wstring tmpInstanceType;
    if(!StructureFamilyUtils::GetFamilyNameByTypeId(pDoc, preSetTypeId, tmpFamilyName))
    {
        return false;
    }

    if(!StructureFamilyUtils::GetInstanceTypeNameByTypeId(pDoc, preSetTypeId, tmpInstanceType))
    {
        return false;
    }

    familyName = tmpFamilyName;
    instanceType = tmpInstanceType;
    return true;
}

bool StructureInstancePresetParameterUtils::SetPresetInstanceType(const IDocument* pDoc, const UniIdentity& categoryUid, Int32 categorySecondKey, ElementId instanceTypeId)
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");

    IPresetParameterManager* pPresetMgr = IPresetParameterManager::Get(pDoc);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pPresetMgr, L"pPresetMgr为空",L"GDMPLab",L"2024-03-30");

    bool bOk = pPresetMgr->SetPresetType(categoryUid, categorySecondKey, instanceTypeId);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(bOk, L"SetPresetType失败",L"GDMPLab",L"2024-03-30");

    return true;
}

bool StructureInstancePresetParameterUtils::GetPresetBaseLevel(const IDocument* pDoc, const UniIdentity& categoryUid, Int32 categorySecondKey, ElementId& baseLevelId)
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");

    IPresetParameterManager* pPresetMgr = IPresetParameterManager::Get(pDoc);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pPresetMgr, L"pPresetMgr为空",L"GDMPLab",L"2024-03-30");

    const IParameter* pParameter = pPresetMgr->GetPresetParameter(categoryUid, categorySecondKey, DOC_PARAMETER_ID(pDoc, ElementAssociatedLevelBuiltInParameter));
    if (pParameter)
    {
        baseLevelId = pParameter->GetValueAsElementId();
        return true;
    }

    return false;
}

bool StructureInstancePresetParameterUtils::GetPresetTopLevel(const IDocument* pDoc, const UniIdentity& categoryUid, Int32 categorySecondKey, ElementId& topLevelId)
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");

    IPresetParameterManager* pPresetMgr = IPresetParameterManager::Get(pDoc);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pPresetMgr, L"pPresetMgr为空",L"GDMPLab",L"2024-03-30");

    const IParameter* pParameter = pPresetMgr->GetPresetParameter(categoryUid, categorySecondKey, DOC_PARAMETER_ID(pDoc, TopAssociatedLevelBuiltInParameter));
    if (pParameter)
    {
        topLevelId = pParameter->GetValueAsElementId();
        return true;
    }

    return false;
}

bool StructureInstancePresetParameterUtils::GetPresetTopLevelOffset(const IDocument* pDoc, const UniIdentity& categoryUid, Int32 categorySecondKey, double& topLevelOffset)
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");

    IPresetParameterManager* pPresetMgr = IPresetParameterManager::Get(pDoc);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pPresetMgr, L"pPresetMgr为空",L"GDMPLab",L"2024-03-30");

    const IParameter* pParameter = pPresetMgr->GetPresetParameter(categoryUid, categorySecondKey, DOC_PARAMETER_ID(pDoc, TopOffsetBuiltInParameter));
    if (pParameter)
    {
        topLevelOffset = pParameter->GetValueAsDouble();
        return true;
    }

    return false;
}

bool StructureInstancePresetParameterUtils::GetPresetStartOffset(const IDocument* pDoc, const UniIdentity& categoryUid, Int32 categorySecondKey, double& startOffset)
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");

    IPresetParameterManager* pPresetMgr = IPresetParameterManager::Get(pDoc);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pPresetMgr, L"pPresetMgr为空",L"GDMPLab",L"2024-03-30");

    const IParameter* pParameter = pPresetMgr->GetPresetParameter(categoryUid, categorySecondKey, DOC_PARAMETER_ID(pDoc, StartOffsetBuiltInParameter));
    if (pParameter)
    {
        startOffset = pParameter->GetValueAsDouble();
        return true;
    }

    return false;
}

bool StructureInstancePresetParameterUtils::GetPresetEndOffset(const IDocument* pDoc, const UniIdentity& categoryUid, Int32 categorySecondKey, double& endOffset)
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");

    IPresetParameterManager* pPresetMgr = IPresetParameterManager::Get(pDoc);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pPresetMgr, L"pPresetMgr为空",L"GDMPLab",L"2024-03-30");

    const IParameter* pParameter = pPresetMgr->GetPresetParameter(categoryUid, categorySecondKey, DOC_PARAMETER_ID(pDoc, EndOffsetBuiltInParameter));
    if (pParameter)
    {
        endOffset = pParameter->GetValueAsDouble();
        return true;
    }

    return false;
}

bool StructureInstancePresetParameterUtils::GetPresetStoryLevel(const IDocument* pDoc, const UniIdentity& categoryUid, Int32 categorySecondKey, ElementId& storeyId)
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");

    IPresetParameterManager* pPresetMgr = IPresetParameterManager::Get(pDoc);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pPresetMgr, L"pPresetMgr为空",L"GDMPLab",L"2024-03-30");

    const IParameter* pParameter = pPresetMgr->GetPresetParameter(categoryUid, categorySecondKey, DOC_PARAMETER_ID(pDoc, BuildingStoreyBuiltInParameter));
    if (pParameter)
    {
        storeyId = pParameter->GetValueAsElementId();
        return true;
    }

    return false;
}

bool StructureInstancePresetParameterUtils::GetPresetZPositioningType(const IDocument* pDoc, const UniIdentity& categoryUid, Int32 categorySecondKey, BeamZPositioningType& type)
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");

    IPresetParameterManager* pPresetMgr = IPresetParameterManager::Get(pDoc);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pPresetMgr, L"pPresetMgr为空",L"GDMPLab",L"2024-03-30");

    const IParameter* pParameter = pPresetMgr->GetPresetParameter(categoryUid, categorySecondKey, DOC_PARAMETER_ID(pDoc, BeamZPositioningTypeBuiltInParameter));
    if (pParameter)
    {
        type = (BeamZPositioningType)pParameter->GetValueAsInt();
        return true;
    }

    return false;
}

bool StructureInstancePresetParameterUtils::GetPresetZPositioningType(const IDocument* pDoc, const UniIdentity& categoryUid, Int32 categorySecondKey, WallHoleZPositioningType& type)
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");

    IPresetParameterManager* pPresetMgr = IPresetParameterManager::Get(pDoc);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pPresetMgr, L"pPresetMgr为空",L"GDMPLab",L"2024-03-30");

    const IParameter* pParameter = pPresetMgr->GetPresetParameter(categoryUid, categorySecondKey, DOC_PARAMETER_ID(pDoc, WallHoleZPositioningTypeBuiltInParameter));
    if (pParameter)
    {
        type = (WallHoleZPositioningType)pParameter->GetValueAsInt();
        return true;
    }

    return false;
}

bool gcmp::StructureInstancePresetParameterUtils::GetPresetBaseLevelOffset(const IDocument* pDoc, const UniIdentity& categoryUid, Int32 categorySecondKey, double& baseLevelOffset)
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");

    IPresetParameterManager* pPresetMgr = IPresetParameterManager::Get(pDoc);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pPresetMgr, L"pPresetMgr为空",L"GDMPLab",L"2024-03-30");

    const IParameter* pParameter = pPresetMgr->GetPresetParameter(categoryUid, categorySecondKey, DOC_PARAMETER_ID(pDoc, BottomOffsetBuiltInParameter));
    if (pParameter)
    {
        baseLevelOffset = pParameter->GetValueAsDouble();
        return true;
    }

    return false;
}

bool gcmp::StructureInstancePresetParameterUtils::GetPresetWallHeight(const IDocument* pDoc, const UniIdentity& categoryUid, Int32 categorySecondKey, double& height)
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");

    IPresetParameterManager* pPresetMgr = IPresetParameterManager::Get(pDoc);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pPresetMgr, L"pPresetMgr为空",L"GDMPLab",L"2024-03-30");

    const IParameter* pParameter = pPresetMgr->GetPresetParameter(categoryUid, categorySecondKey, DOC_PARAMETER_ID(pDoc, WallHeightBuiltInParameter));
    if (pParameter)
    {
        height = (double)pParameter->GetValueAsDouble();
        return true;
    }

    return false;
}

bool gcmp::StructureInstancePresetParameterUtils::GetPresetWallStartHeight(const IDocument* pDoc, const UniIdentity& categoryUid, Int32 categorySecondKey, double& height)
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");

    IPresetParameterManager* pPresetMgr = IPresetParameterManager::Get(pDoc);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pPresetMgr, L"pPresetMgr为空",L"GDMPLab",L"2024-03-30");

    const IParameter* pParameter = pPresetMgr->GetPresetParameter(categoryUid, categorySecondKey, DOC_PARAMETER_ID(pDoc, StartHeightBuiltInParameter));
    if (pParameter)
    {
        height = (double)pParameter->GetValueAsDouble();
        return true;
    }

    return false;
}

bool gcmp::StructureInstancePresetParameterUtils::GetPresetWallEndHeight(const IDocument* pDoc, const UniIdentity& categoryUid, Int32 categorySecondKey, double& height)
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");

    IPresetParameterManager* pPresetMgr = IPresetParameterManager::Get(pDoc);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pPresetMgr, L"pPresetMgr为空",L"GDMPLab",L"2024-03-30");

    const IParameter* pParameter = pPresetMgr->GetPresetParameter(categoryUid, categorySecondKey, DOC_PARAMETER_ID(pDoc, EndHeightBuiltInParameter));
    if (pParameter)
    {
        height = (double)pParameter->GetValueAsDouble();
        return true;
    }

    return false;
}

bool gcmp::StructureInstancePresetParameterUtils::GetPresetWallStartOffset(const IDocument* pDoc, const UniIdentity& categoryUid, Int32 categorySecondKey, double& offest)
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");

    IPresetParameterManager* pPresetMgr = IPresetParameterManager::Get(pDoc);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pPresetMgr, L"pPresetMgr为空",L"GDMPLab",L"2024-03-30");

    const IParameter* pParameter = pPresetMgr->GetPresetParameter(categoryUid, categorySecondKey, DOC_PARAMETER_ID(pDoc, StartBottomAssociatedLevelOffsetBuiltInParameter));
    if (pParameter)
    {
        offest = (double)pParameter->GetValueAsDouble();
        return true;
    }

    return false;
}

bool gcmp::StructureInstancePresetParameterUtils::GetPresetWallEndOffest(const IDocument* pDoc, const UniIdentity& categoryUid, Int32 categorySecondKey, double& offest)
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");

    IPresetParameterManager* pPresetMgr = IPresetParameterManager::Get(pDoc);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pPresetMgr, L"pPresetMgr为空",L"GDMPLab",L"2024-03-30");

    const IParameter* pParameter = pPresetMgr->GetPresetParameter(categoryUid, categorySecondKey, DOC_PARAMETER_ID(pDoc, EndBottomAssociatedLevelOffsetBuiltInParameter));
    if (pParameter)
    {
        offest = (double)pParameter->GetValueAsDouble();
        return true;
    }

    return false;
}

bool gcmp::StructureInstancePresetParameterUtils::GetPresetZPositioningType(const IDocument* pDoc, const UniIdentity& categoryUid, Int32 categorySecondKey, RaftFoundationZPositioningType& type)
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");

    IPresetParameterManager* pPresetMgr = IPresetParameterManager::Get(pDoc);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pPresetMgr, L"pPresetMgr为空",L"GDMPLab",L"2024-03-30");

    const IParameter* pParameter = pPresetMgr->GetPresetParameter(categoryUid, categorySecondKey, DOC_PARAMETER_ID(pDoc, RaftFoundationZPositioningTypeBuiltInParameter));
    if (pParameter)
    {
        type = (RaftFoundationZPositioningType)pParameter->GetValueAsInt();
        return true;
    }

    return false;
}

bool gcmp::StructureInstancePresetParameterUtils::GetPresetZPositioningType(const IDocument* pDoc, const UniIdentity& categoryUid, Int32 categorySecondKey, StripFoundationZPositioningType& type)
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");

    IPresetParameterManager* pPresetMgr = IPresetParameterManager::Get(pDoc);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pPresetMgr, L"pPresetMgr为空",L"GDMPLab",L"2024-03-30");

    const IParameter* pParameter = pPresetMgr->GetPresetParameter(categoryUid, categorySecondKey, DOC_PARAMETER_ID(pDoc, StripFoundationZPositioningTypeBuiltInParameter));
    if (pParameter)
    {
        type = (StripFoundationZPositioningType)pParameter->GetValueAsInt();
        return true;
    }

    return false;
}

bool gcmp::StructureInstancePresetParameterUtils::GetPresetConcreteStrengthGradeType(const IDocument* pDoc, const UniIdentity& categoryUid, Int32 categorySecondKey, ConcreteStrengthGradeType& type)
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");

    IPresetParameterManager* pPresetMgr = IPresetParameterManager::Get(pDoc);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pPresetMgr, L"pPresetMgr为空",L"GDMPLab",L"2024-03-30");

    const IParameter* pParameter = pPresetMgr->GetPresetParameter(categoryUid, categorySecondKey, DOC_PARAMETER_ID(pDoc, ConcreteStrengthGradeBuiltInParameter));
    if (pParameter)
    {
        type = (ConcreteStrengthGradeType)pParameter->GetValueAsInt();
        return true;
    }

    return false;
}

bool gcmp::StructureInstancePresetParameterUtils::GetPreSetColumnHeight(const IDocument* pDoc, const UniIdentity& categoryUid, Int32 categorySecondKey, double& height)
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");

    IPresetParameterManager* pPresetMgr = IPresetParameterManager::Get(pDoc);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pPresetMgr, L"pPresetMgr为空",L"GDMPLab",L"2024-03-30");

    const IParameter* pParameter = pPresetMgr->GetPresetParameter(categoryUid, categorySecondKey, DOC_PARAMETER_ID(pDoc, ColumnHeightBuiltInParameter));
    if (pParameter)
    {
        height = (double)pParameter->GetValueAsDouble();
        return true;
    }

    return false;
}

bool gcmp::StructureInstancePresetParameterUtils::GetPresetSlantedColumnTopFaceEndType(const IDocument* pDoc, const UniIdentity& categoryUid, Int32 categorySecondKey, InstanceEndType& type)
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");

    IPresetParameterManager* pPresetMgr = IPresetParameterManager::Get(pDoc);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pPresetMgr, L"pPresetMgr为空",L"GDMPLab",L"2024-03-30");

    const IParameter* pParameter = pPresetMgr->GetPresetParameter(categoryUid, categorySecondKey, DOC_PARAMETER_ID(pDoc, ColumnTopSectionType));
    if (pParameter)
    {
        type =(InstanceEndType) pParameter->GetValueAsInt();
        return true;
    }

    return false;
}
bool gcmp::StructureInstancePresetParameterUtils::GetPresetSlantedColumnBottomFaceEndType(const IDocument* pDoc, const UniIdentity& categoryUid, Int32 categorySecondKey, InstanceEndType& type)
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");

    IPresetParameterManager* pPresetMgr = IPresetParameterManager::Get(pDoc);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pPresetMgr, L"pPresetMgr为空",L"GDMPLab",L"2024-03-30");

    const IParameter* pParameter = pPresetMgr->GetPresetParameter(categoryUid, categorySecondKey, DOC_PARAMETER_ID(pDoc, ColumnBottomSectionType));
    if (pParameter)
    {
        type = (InstanceEndType)pParameter->GetValueAsInt();
        return true;
    }

    return false;
}

bool gcmp::StructureInstancePresetParameterUtils::GetPresetSlantedColumnSectionRotateAngle(const IDocument* pDoc, const UniIdentity& categoryUid, Int32 categorySecondKey, double& angle)
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");

    IPresetParameterManager* pPresetMgr = IPresetParameterManager::Get(pDoc);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pPresetMgr, L"pPresetMgr为空",L"GDMPLab",L"2024-03-30");

    const IParameter* pParameter = pPresetMgr->GetPresetParameter(categoryUid, categorySecondKey, DOC_PARAMETER_ID(pDoc, SectionRotateAngleBuiltInParameter));
    if (pParameter)
    {
        angle = pParameter->GetValueAsDouble();
        return true;
    }

    return false;
}
